from django import forms
from django.contrib import messages
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render, redirect, get_object_or_404

from StuApp.models import GradeInfo, StudentInfo


# 学生信息
class StudentForm(forms.ModelForm):
    class Meta:
        model = StudentInfo
        fields = ['student_id', 'student_name', 'student_gender', 'student_profession', 'student_birthday', 'student_phone', 'student_class']

    # 通过重写方法，设置学号为只读, 并且添加bootstrap样式
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'
            if name == 'student_birthday':
                field.widget = forms.DateInput(attrs={
                    'class': 'form-control',
                    'type': 'date'
                })

    def clean_student_id(self):
        student_id = self.cleaned_data['student_id']
        if StudentInfo.objects.filter(student_id=student_id).exists():
            raise forms.ValidationError(f'学号 {student_id} 已存在！')
        return student_id


class EditStudentForm(forms.ModelForm):
    class Meta:
        model = StudentInfo
        fields = ['student_id', 'student_name', 'student_gender', 'student_profession', 'student_birthday', 'student_phone', 'student_class']

    # 重写init方法，设置bootstrap样式
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'
            if name == 'student_birthday':
                field.widget = forms.DateInput(attrs={
                    'class': 'form-control',
                    'type': 'date' # 日期选择框
                })
        # 学号只读
        self.fields['student_id'].widget.attrs['readonly'] = True

    def clean_student_id(self):
        student_id = self.cleaned_data['student_id']
        if StudentInfo.objects.filter(student_id=student_id).exclude(pk=self.instance.pk).exists():
            raise forms.ValidationError(f'学号 {student_id} 已存在！')
        return student_id


# 学生列表
def stuList(request):
    # 获取所有年级，专业信息
    grades = GradeInfo.objects.all().order_by('grade_id')

    # 获取查询参数
    search_type = request.GET.get('search_type', 'name')  # 默认按姓名
    search_key = request.GET.get('search', '')
    grade_filter = request.GET.get('grade', '')
    profession_filter = request.GET.get('profession', '')

    stu_list = StudentInfo.objects.all()
    if search_key:
        if search_type == 'name':
            stu_list = stu_list.filter(student_name__icontains=search_key) # 包含查询
        elif search_type == 'id':
            stu_list = stu_list.filter(student_id__icontains=search_key)

    if grade_filter:
        stu_list = stu_list.filter(student_class__grade_id=grade_filter) # 跨表查询，根据年级id在学生表中查询

    if profession_filter:
        stu_list = stu_list.filter(student_profession=profession_filter) # 根据专业在学生表中查询

    stu_list = stu_list.order_by('student_id') # 根据学号排序

    # 分页
    paginator = Paginator(stu_list, 10) # 每页10条数据
    page = request.GET.get('page', 1) # 获取当前页码
    page = int(page)
    stu_list = paginator.page(page) # 分页查询

    dict_data = {
        'stu_list': stu_list, # 学生列表
        'page_obj': stu_list, # 分页对象
        'search_key': search_key, # 搜索关键字
        'grades': grades, # 年级列表
        'grade_filter': grade_filter, # 年级过滤
        'profession_filter': profession_filter, # 专业过滤
        'professions': StudentInfo.profession_choices, # 专业列表
        'search_type': search_type, # 搜索类型
    }

    # 渲染模板
    return render(request, 'stu_info.html', dict_data)


# 添加学生
def addStu(request):
    if request.method == 'POST':
        form = StudentForm(request.POST)
        if form.is_valid():
            student_id = form.cleaned_data['student_id']
            # 检查学号是否已存在
            if StudentInfo.objects.filter(student_id=student_id).exists():
                messages.error(request, f'学号 {student_id} 已存在！')
                return render(request, 'add.html', {"form": form, "title": "学生"})

            try:
                form.save()
                messages.success(request, f'学生 {form.cleaned_data["student_name"]} 添加成功！')
                return redirect('stu_list')
            except Exception as e:
                messages.error(request, f'添加学生失败：{str(e)}')
                return render(request, 'add.html', {"form": form, "title": "学生"})

        else:
            # 表单验证失败，显示具体的错误信息
            for field, errors in form.errors.items():
                for error in errors:
                    messages.error(request, f'{form.fields[field].label}: {error}')
            return render(request, 'add.html', {"form": form, "title": "学生"})
    else:
        form = StudentForm()
    return render(request, 'add.html', {"form": form, "title": "学生"})


# 删除学生（通用模板，ajax请求）
def deleteStu(request, stu_id):
    if request.method == 'POST':
        try:
            stu = StudentInfo.objects.get(student_id=stu_id)
            stu.delete()
            return JsonResponse({'status': 'success'})
        except StudentInfo.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': '学生不存在'})
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': str(e)})
    return JsonResponse({'status': 'error', 'message': '无效的请求方法'})


# 更新学生信息
def updateStu(request, stu_id):
    student = get_object_or_404(StudentInfo, student_id=stu_id)
    if request.method == 'GET':
        form = EditStudentForm(instance=student)
        return render(request, 'edit_layout.html', {
            "form": form, # 表单
            "title": "学生", # 标题
            "student_obj": student # 学生对象
        })
    elif request.method == 'POST':
        form = EditStudentForm(request.POST, instance=student)
        if form.is_valid():
            form.save()
            messages.success(request, '修改成功！')
            return redirect('stu_list')
        else:
            messages.error(request, '修改失败！')
            return render(request, 'edit_layout.html', {
                "form": form,
                "title": "学生",
                "student_obj": student
            })
